//
// Created by 33145 on 2023/6/2.
//

#include "net_addr.h"

#include <utility>
#include "../common/rocket.h"
#include <cstring>

namespace rocket {

  IPNetAddr::IPNetAddr(const std::string& ip, uint16_t port) : _ip(ip), _port(port) {
    memset(&_addr, 0, sizeof _addr);

    _addr.sin_addr.s_addr = inet_addr(_ip.c_str());
    _addr.sin_port = htons(port);
    _addr.sin_family = AF_INET;
  }

  IPNetAddr::IPNetAddr(const std::string &addr) {
    size_t i = addr.find_first_of(":");
    if (i == addr.npos) {
      LOG_ERROR("find_first_of(\":\") error : [%s]", addr.c_str());
    } else {
      _ip = addr.substr(0, i);
      _port = std::atoi(addr.substr(i + 1, addr.size() - i - 1).c_str());

      memset(&_addr, 0, sizeof _addr);
      _addr.sin_family = AF_INET;
      _addr.sin_port = htons(_port);
      _addr.sin_addr.s_addr = inet_addr(_ip.c_str());
    }
  }

  IPNetAddr::IPNetAddr(sockaddr_in addr) : _addr(addr) {
    _ip = std::string(inet_ntoa(_addr.sin_addr));
    _port = ntohs(_addr.sin_port);
  }

  sockaddr *IPNetAddr::getSockAddr() {
    return reinterpret_cast<sockaddr*> (&_addr);
  }

  socklen_t IPNetAddr::getSockLen() {
    return sizeof _addr;
  }

  int IPNetAddr::getFamily() {
    return AF_INET;
  }

  std::string IPNetAddr::toString() {
    return _ip + ":" + std::to_string(_port);
  }

  bool IPNetAddr::checkValid() {
    if (_ip.empty()) {
      return false;
    }
    if (_port < 0) {
      return false;
    }
    if (inet_addr(_ip.c_str()) == INADDR_NONE) {
      return false;
    }
    return true;
  }
}